<template>
  <form class="cmp cmp-tripledes row">
    <div class="col-5">
      <fieldset>
        <legend>输入</legend>
        <div class="fieldset-content">
          <textarea class="form-control" v-model.trim="inputContent" placeholder="请输入要处理的文本"></textarea>
        </div>
      </fieldset>
    </div>
    <div class="col-2">
      <div class="form-group-list">
        <div class="form-group">
          <select class="form-control" v-model="decryptMode" placeholder="解密模式">
            <option v-for="(v,i) in decryptModeList" :key="i" :value="v.value">{{v.label}}</option>
          </select>
        </div>
        <div class="form-group">
          <select class="form-control" v-model="decryptPadding" placeholder="填充方式">
            <option v-for="(v,i) in decryptPaddingList" :key="i" :value="v.value">{{v.label}}</option>
          </select>
        </div>
        <div class="form-group" v-if="decryptMode!=='ECB'">
          <input class="form-control" type="text" v-model.trim="iv" placeholder="偏移量IV" />
        </div>
        <div class="form-group" v-if="(['OFB', 'CFB'].includes(decryptMode))">
          <input class="form-control" type="text" v-model.trim="blockSize" placeholder="BlockSize" />
        </div>
        <div class="form-group">
          <input class="form-control" type="text" v-model.trim="key" placeholder="请输入字符串key" />
        </div>
        <div class="form-group">
          <x-button type="primary" block @click="encrypt">加 密</x-button>
        </div>
        <div class="form-group">
          <x-button type="primary" block @click="decrypt">解 密</x-button>
        </div>
      </div>
    </div>
    <div class="col-5">
      <fieldset>
        <legend>输出</legend>
        <div class="fieldset-content">
          <textarea class="form-control" v-model.trim="outputContent" placeholder="处理后的结果" readonly></textarea>
        </div>
      </fieldset>
    </div>
  </form>
</template>

<script>
let CryptoJS = global.CryptoJS || {}

export default {
  name: 'tripledes',
  data () {
    return {
      inputContent: '',
      outputContent: '',
      decryptMode: 'CBC',
      decryptPadding: 'Pkcs7',
      iv: '',
      blockSize: '',
      key: '',
      decryptModeList: [
        {label: 'CBC', value: 'CBC'},
        {label: 'ECB', value: 'ECB'},
        {label: 'CTR', value: 'CTR'},
        {label: 'CTRGladman', value: 'CTRGladman'},
        {label: 'OFB', value: 'OFB'},
        {label: 'CFB', value: 'CFB'},
      ],
      decryptPaddingList: [
        {label: 'Pkcs7', value: 'Pkcs7'},
        {label: 'ZeroPadding', value: 'ZeroPadding'},
        {label: 'Iso10126', value: 'Iso10126'},
        {label: 'Iso97971', value: 'Iso97971'},
        {label: 'AnsiX923', value: 'AnsiX923'},
        {label: 'NoPadding', value: 'NoPadding'},
      ],
    }
  },
  methods: {
    // 表单校验
    checkForm () {
      let result = true
      if (!this.inputContent) {
        result = false
        this.$toast('请输入要处理的文本')
      }
      if (!this.key) {
        result = false
        this.$toast('请输入秘钥')
      }
      return result
    },
    // 加密
    encrypt () {
      if (!this.checkForm()) return
      this.outputContent = ''
      let key = CryptoJS.enc.Utf8.parse(this.key)
      let options = {
        mode: CryptoJS.mode[this.decryptMode],
        padding: CryptoJS.pad[this.decryptPadding]
      }
      if (this.decryptMode !== 'ECB') {
        options.iv = CryptoJS.enc.Utf8.parse(this.iv)
      }
      let encrypted = CryptoJS.TripleDES.encrypt(this.inputContent, key, options)
      encrypted = encrypted.ciphertext.toString()
      this.outputContent = encrypted
    },
    // 解密
    decrypt () {
      if (!this.checkForm()) return
      this.outputContent = ''
      let key = CryptoJS.enc.Utf8.parse(this.key)
      let options = {
        mode: CryptoJS.mode[this.decryptMode],
        padding: CryptoJS.pad[this.decryptPadding]
      }
      if (this.decryptMode !== 'ECB') {
        options.iv = CryptoJS.enc.Utf8.parse(this.iv)
      }
      let encrypted = CryptoJS.enc.Hex.parse(this.inputContent)
      let base64Str = CryptoJS.enc.Base64.stringify(encrypted)
      let decrypted = CryptoJS.TripleDES.decrypt(base64Str, key, options)
      decrypted = decrypted.toString(CryptoJS.enc.Utf8)
      this.outputContent = decrypted
    },
  }
}
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";
.cmp-tripledes {
  height: 100%;
  fieldset {
    height: 100%;
    .fieldset-content {
      height: calc(100% - 2em);
      textarea {
        display: block;
        height: 100%;
      }
    }
  }
  .form-group-list {
    height: 100%;
    padding: .5vw;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}
</style>
